做了 28 天,這個遊戲一直只有我自己的電腦看得到。今天要把它放到網路上。
https://lucy-zhang-odo.github.io/ironman-js-battle/
不用安裝任何東西,手機也可以。
GitHub 有一個功能叫 Pages:把靜態網頁(HTML/CSS/JS)放進 repo,它就會幫你架成一個公開網站。不用租主機、不用設定、不用付錢。
我做的事只有兩步:
第一步:把遊戲放到 repo 根目錄。
前面 28 天每天一個資料夾,最新的版本在 day28/。但如果直接用那個路徑,網址會變成 .../ironman-js-battle/day28/ —— 很難念,而且以後改版還要換網址。
所以我把 index.html、style.css、game.js 複製到根目錄。這樣網址就是乾淨的 .../ironman-js-battle/。
這裡用到的是 Day 23 學到的規則:伺服器看到資料夾網址,會自動去找 index.html。當時只是知道有這個慣例,今天才真的靠它拿到一個乾淨的網址。
第二步:在 repo 的 Settings → Pages,把來源設成 main 分支的根目錄。
存檔之後等一兩分鐘,網址就活了。整個過程比我以為的簡單太多 —— 我原本以為「上線」是一件要處理很多設定的事。
<title>勇者 vs 小怪 —— QA 的 JavaScript 初心之路</title>
<meta name="description" content="一名軟體測試工程師從零開始學 JavaScript,30 天做出的回合制戰鬥小遊戲。">
<link rel="icon" href="data:image/svg+xml,<svg ...><text y='.9em' font-size='90'>⚔️</text></svg>">
<title> 和 description 是分享連結時會顯示的文字。而 favicon 我用了一個小技巧:直接把一個 emoji 包成 SVG 寫在網址裡,不需要額外準備圖檔。分頁上就會出現一把劍。
這用到的是 Day 13 學的 data: 寫法 —— 當時是為了理解 XSS 的攻擊手法,今天拿來做一個完全無害的用途。
打開網址,「最少回合紀錄」顯示尚無。
但我在本機明明打出過 9 回合的紀錄。
想了一下才反應過來:localStorage 是跟著「網域」走的。本機的網址是 127.0.0.1:5500,線上是 lucy-zhang-odo.github.io —— 對瀏覽器來說,這是兩個完全不同的地方,資料當然不共用。
這其實是安全機制:如果不同網站的 localStorage 可以互通,那任何一個網頁都能讀到你在別的網站存的東西。Day 20 學這個工具的時候只知道「存在瀏覽器裡」,今天才理解「存在哪個網站的瀏覽器空間裡」。
同一份程式碼、換一個網址,資料就是全新的。這也表示:每個玩家的紀錄都只屬於他自己,沒有共用的排行榜 —— 那正是我留給明年的功能。
這是第一次在真的手機上開,而不是把電腦瀏覽器的視窗拉窄。
結果比我預期好:版面正常、按鈕好按、名字輸入框沒問題。昨天做的 @media (max-width: 420px) 調整有發揮作用。
不過「拉窄視窗」和「真的用手機」確實不是同一回事 —— 差別在觸控、在實際的手指大小、在真實的螢幕比例。能模擬的先模擬,但最後還是要上真機。 這跟測試工作上的原則完全一樣。
明天就完賽了。回頭看這 29 天,如果要畫一條難度曲線,它不是一路往上,而是波浪型。
Day 1–12:平緩往上。 學語法的階段,每天一個新東西:變數、字串、判斷、陣列、物件、迴圈、函式。難度穩定增加,但每一天的份量差不多。
Day 13–21:持續爬坡。 開始把零件組起來,而且每天都要做決定 —— 要不要用計時器、紀錄該存什麼、bug 該怎麼找。程式越長,腦中要同時記住的東西越多。
Day 21 之後難度並沒有下降,而是繼續升高。 那時候所有東西都擠在一個檔案裡,三百多行,想改一個地方得先捲很久確認自己在哪。我看得很吃力。
Day 23 拆成三個檔案之後,難度明顯下降了。
這是整條曲線上最有感的一個轉折:HTML 管結構、CSS 管外觀、JS 管邏輯,各自一個檔案。程式碼沒有變少,但要找的東西變好找了。
當然這不是說之後就輕鬆了。越複雜的設計,要看懂、要理解就越困難 —— Day 27 的增益系統、Day 25 那個非同步競態,都比前面任何一天的語法難。只是那種難是「這個機制怎麼運作」的難,不再是「我到底在哪一行」的難。
所以曲線的形狀是:爬坡 → 更陡 → 拆檔案後降一階 → 再爬,但是爬得比較穩。
如果只能挑一個,對我這個職業來說,最大的收穫是查 bug 的方式。
以前我找到 bug,能做的是描述現象、寫重現步驟、附上截圖,然後交給工程師。至於「為什麼會這樣」,我不知道,也沒有工具可以知道。
這 29 天下來,我學會的是另一套東西:
最後兩項是我最意外的收穫。我原本以為「自動化測試」是工程師的事,結果我在 Day 24 為了驗證數值平衡,自己寫了一個模擬器 —— 那是我第一次真的寫出一個測試工具,而不是使用別人做好的。
而 Day 21 那天最有價值的體會,其實跟程式無關:
一個 bug 要能被發現,前提是有人知道正確的行為應該是什麼。
這句話解釋了我工作上很多說不清楚的挫折 —— 為什麼有些問題上線好幾年才被發現、為什麼「使用者沒反應」不等於「沒問題」。答案通常是:沒有人知道那裡本來應該長什麼樣。
照慣例,完賽前夕應該給一段「對想轉職的同行的話」。
但我不打算給建議。
與其給建議,不如說說我為什麼開始:因為薪水。
Day 1 我就寫了 —— 我是一名 QA,薪水不高,在想轉職。同事說全端可以從 JavaScript 入手,主管說參加鐵人賽可以豐富履歷。我想不到 AI Engineering 要以什麼樣的完成度結案,所以選了一個看得見成果的方向:做一個小時候玩過的那種網頁遊戲。
整件事的起點就是這麼現實,沒有什麼「對技術的熱愛」。
如果你也是,那你已經有答案了。 你不需要我告訴你該不該學,你需要的是一個做得完的目標,和一個每天願意坐下來的理由。
我的理由是「明天想看到那個畫面動起來」。這 29 天我沒有一天是因為責任感才打開編輯器的 —— 我是想知道今天加上去的東西會長什麼樣子。
那個理由夠不夠撐 30 天,只有你自己知道。
今天做的事:
index.html,網址才乾淨(Day 23 學的伺服器慣例)data: 網址把 emoji 包成 SVG 當 favicon,不用準備圖檔29 天的心得:
明天完賽。而且我藏了兩個東西,明天一起揭曉。